package com.nantong.admin.service.impl;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;

import com.nantong.admin.domain.SysRole;
import com.nantong.admin.domain.SysRolePermission;
import com.nantong.admin.domain.model.request.role.RoleSearch;
import com.nantong.admin.domain.model.response.role.SysRoleVo;
import com.nantong.admin.mapper.SysRoleMapper;
import com.nantong.admin.mapper.SysRolePermissionMapper;
import com.nantong.admin.service.ISysRoleService;
import com.nantong.common.mybatis.core.page.PageQuery;
import com.nantong.common.mybatis.core.page.TableDataInfo;

import org.springframework.stereotype.Service;

/**
 * 角色 业务层处理
 *
 * @author nantong
 */
@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {

    private final SysRoleMapper roleMapper;
    private final SysRolePermissionMapper rolePermissionMapper;

    /**
     * 根据用户ID查询角色
     *
     * @param userId 用户ID
     * @return 角色列表
     */
    @Override
    public List<SysRole> selectRolesByUserId(Long userId) {
        return roleMapper.selectRolesByUserId(userId);
    }

    /**
     * 根据用户ID查询角色权限字符串
     *
     * @param userId 用户ID
     * @return 角色权限字符串列表
     */
    @Override
    public Set<String> selectRoleKeysByUserId(Long userId) {
        List<String> roleKeys = roleMapper.selectRoleKeysByUserId(userId);
        return new HashSet<>(roleKeys);
    }

    /**
     * 校验角色名称是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public boolean checkRoleNameUnique(SysRole role) {
        Long roleId = role.getRoleId() == null ? -1L : role.getRoleId();
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleName, role.getRoleName());
        SysRole info = roleMapper.selectOne(queryWrapper);
        return info == null || info.getRoleId().equals(roleId);
    }

    /**
     * 校验角色权限是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    @Override
    public boolean checkRoleKeyUnique(SysRole role) {
        Long roleId = role.getRoleId() == null ? -1L : role.getRoleId();
        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysRole::getRoleKey, role.getRoleKey());
        SysRole info = roleMapper.selectOne(queryWrapper);
        return info == null || info.getRoleId().equals(roleId);
    }

    /**
     * 通过角色ID查询角色
     *
     * @param roleId 角色ID
     * @return 角色对象信息
     */
    @Override
    public SysRole selectRoleById(Long roleId) {
        return roleMapper.selectById(roleId);
    }

    @Override
    public TableDataInfo<SysRoleVo> selectPageList(RoleSearch pageQuery, PageQuery query) {
        LambdaQueryWrapper<SysRole> lqw = new LambdaQueryWrapper<>();
        lqw.like(StrUtil.isNotBlank(pageQuery.getRoleName()), SysRole::getRoleName, pageQuery.getRoleName())
                .like(StrUtil.isNotBlank(pageQuery.getRoleKey()), SysRole::getRoleKey, pageQuery.getRoleKey())
                .eq(pageQuery.getStatus() != null, SysRole::getStatus, pageQuery.getStatus())
                // 按照排序号正序、创建时间倒序排列
                .orderByAsc(SysRole::getRoleSort)
                .orderByDesc(SysRole::getCreateTime);

        Page<SysRoleVo> page = roleMapper.selectVoPage(query.build(), lqw);
        return TableDataInfo.build(page);
    }

    /**
     * 获取角色拥有的权限ID列表
     *
     * @param roleId 角色ID
     * @return 权限ID列表
     */
    @Override
    public List<Long> listPermissionIdsByRoleId(Long roleId) {
        // 通过角色ID查询该角色已经拥有的权限ID列表
        return roleMapper.selectPermissionIdsByRoleId(roleId);
    }

    /**
     * 为角色分配权限
     *
     * @param roleId        角色ID
     * @param permissionIds 权限ID列表
     */
    @Override
    public void assignRolePermissions(Long roleId, List<Long> permissionIds) {
        // 查询原来的角色拥有的权限
        LambdaQueryWrapper<SysRolePermission> rolePermissionWrapper = new LambdaQueryWrapper<>();
        rolePermissionWrapper.eq(SysRolePermission::getRoleId, roleId);
        List<Long> oldPermissionIds = rolePermissionMapper.selectList(rolePermissionWrapper).stream()
                .map(SysRolePermission::getPermissionId).toList();

        // 如果原来的权限列表跟现在的不一样，则删除之前的
        if (!oldPermissionIds.equals(permissionIds)) {
            rolePermissionMapper.delete(rolePermissionWrapper);
        }

        // 如果权限ID列表不为空，则批量插入新的权限关系
        if (CollUtil.isNotEmpty(permissionIds)) {
            roleMapper.insertRolePermissions(roleId, permissionIds);
        }
    }
}
